/************************************************************************************************
* Title:
* 
*
*************************************************************************************************/
#ifndef __SMURFSBSPNODE_H__
#define __SMURFSBSPNODE_H__

#include "SmurfsPlane.h"
#include "SmurfsPolygon.h"

#include <vector>
#include <limits>
#include <assert.h>

#define PLANE_THICKNESS_EPSILON FLT_EPSILON * 2.0f
#define	MAX_DEPTH 40
#define MIN_LEAF_SIZE 5

enum PolygonClassification {
	COPLANAR_WITH_PLANE,
	IN_FRONT_OF_PLANE,
	BEHIND_PLANE,
	STRADDLING_PLANE
};

enum PointClassification {
	POINT_IN_FRONT_OF_PLANE,
	POINT_BEHIND_PLANE,
	POINT_ON_PLANE
};

class BSPNode {
public:
	BSPNode(void);
	BSPNode(std::vector<SmurfsPolygon*> polygons);
	BSPNode(BSPNode* front, BSPNode* back, SmurfsPlane* plane);
	~BSPNode(void);

	static BSPNode* buildBSPTree(std::vector<SmurfsPolygon*>& polygons, int depth);
	static SmurfsPlane pickSplittingPlane(std::vector<SmurfsPolygon*>& polygons);
	static void splitPolygon(SmurfsPolygon& polygon, SmurfsPlane splitPlane, 
		SmurfsPolygon** frontPoly, int& numFP, SmurfsPolygon** backPoly, int& numBP);
	static PointClassification classifyPointToPlane(Vector3 point, SmurfsPlane plane);
	static PolygonClassification classifyPolygonToPlane(SmurfsPolygon* polygon, SmurfsPlane plane);
private:
	std::vector<SmurfsPolygon*> polygons;
	BSPNode* frontChild;
	BSPNode* backChild;
	SmurfsPlane* splitPlane;
};

#endif